//
// Created by Administrator on 2020/9/17.
//

#ifndef P2PCLIENT_STUN_H
#define P2PCLIENT_STUN_H

#include <cstdint>
#include <cstring>

/// define stun address families
const  uint8_t  IPv4Family = 0x01;
const  uint8_t  IPv6Family = 0x02;

const  uint8_t PropsPortEven = 0x00;
const  uint8_t PropsPortPair = 0x80;
const  uint8_t PropsNone     = 0xFF;

// The following are codepoints used in the requested transport header, they
// are the same values used in the IPv4 and IPv6 headers
const  uint32_t RequestedTransportUdp = 17;
const  uint32_t RequestedTransportTcp = 6;

// define  flags
const  uint32_t ChangeIpFlag   = 0x04;
const  uint32_t ChangePortFlag = 0x02;


// Message Type - from RFC5389
//
//        0                   1                   2                   3
//        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//       |0 0|     STUN Message Type     |         Message Length        |
//       |   |M|M|M|M|M|C|M|M|M|C|M|M|M|M|                               |
//       |   |1|1|9|8|7|1|6|5|4|0|3|2|1|0|                               |
//       |   |1|0| | | | | | | | | | | | |                               |
//       |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
//
// M11 through M0 represent a 12-bit encoding of the method
// C1 through C0 represent a 2 bit encoding of the class.
// 2-bit Class Values are: 00=Request,
//                         01=Indicaiton,
//                         10=Success Response,
//                         11=Error Response
//

const  uint16_t StunClassRequest            = 0x0000;
const  uint16_t StunClassIndication         = 0x0010;
const  uint16_t StunClassSuccessResponse    = 0x0100;
const  uint16_t StunClassErrorResponse      = 0x0110;

// define types for a stun message - RFC5389
const  uint16_t BindMethod                  = 0x001;
const  uint16_t SharedSecretMethod          = 0x002;  // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)

// define types for a turn message - per RFC5766
const  uint16_t TurnAllocateMethod          = 0x003;
const  uint16_t TurnRefreshMethod           = 0x004;
const  uint16_t TurnSendMethod              = 0x006;  // indication only
const  uint16_t TurnDataMethod              = 0x007;  // indication only
const  uint16_t TurnCreatePermissionMethod  = 0x008;
const  uint16_t TurnChannelBindMethod       = 0x009;

// define  stun attribute - RFC5389
// Comprehension required attributes
const  uint16_t MappedAddress    = 0x0001;
const  uint16_t ResponseAddress  = 0x0002;  // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
const  uint16_t ChangeRequest    = 0x0003;  // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
const  uint16_t SourceAddress    = 0x0004;  // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
const  uint16_t ChangedAddress   = 0x0005;  // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
const  uint16_t Username         = 0x0006;
const  uint16_t Password         = 0x0007;  // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
const  uint16_t MessageIntegrity = 0x0008;
const  uint16_t ErrorCode        = 0x0009;
const  uint16_t UnknownAttribute = 0x000A;
const  uint16_t ReflectedFrom    = 0x000B;  // deprecated by RFC5389 (used for backwards compatibility to RFC3489 only)
const  uint16_t Realm            = 0x0014;
const  uint16_t Nonce            = 0x0015;
const  uint16_t XorMappedAddress = 0x0020;
const  uint16_t XorMappedAddress_old = 0x8020; // deprecated
// Comprehension Optional Attributes
const  uint16_t Software         = 0x8022;
const  uint16_t AlternateServer  = 0x8023;
const  uint16_t Fingerprint      = 0x8028;
const  uint16_t SecondaryAddress = 0x8050;  // Non standard extension

// TURN specific message attributes - from behave-turn-12
const  uint16_t TurnChannelNumber      = 0x000C;
const  uint16_t TurnLifetime           = 0x000D;
const  uint16_t TurnBandwidth          = 0x0010; // reserved (removed from latest draft)
const  uint16_t TurnXorPeerAddress     = 0x0012;
const  uint16_t TurnData               = 0x0013;
const  uint16_t TurnXorRelayedAddress  = 0x0016;
const  uint16_t TurnEvenPort           = 0x0018;
const  uint16_t TurnRequestedTransport = 0x0019;
const  uint16_t TurnDontFragment       = 0x001a;
//const  uint16_t TurnTimerVal         = 0x0021; // reserved (removed from latest draft)
const  uint16_t TurnReservationToken   = 0x0022;
const  uint16_t TurnConnectStat        = 0x0023; // tcp allocations
const  uint16_t TurnRequestedAddressFamily = 0x0017; // RFC 6156

// ICE specific message attributes - from draft-ietf-mmusic-ice-19
const  uint16_t IcePriority            = 0x0024;
const  uint16_t IceUseCandidate        = 0x0025;
const  uint16_t IceControlled          = 0x8029;
const  uint16_t IceControlling         = 0x802A;

const  uint32_t StunMagicCookie  = 0x2112A442;


typedef struct { uint32_t longpart[4]; }  UInt128;
typedef struct { uint32_t longpart[3]; }  UInt96;


uint16_t ntoh16(const uint16_t& input);
uint32_t ntoh32(const uint32_t& input);
uint64_t ntoh64(const uint64_t& input);


#endif //P2PCLIENT_STUN_H
